<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
</head>
<body>
这里是样式
</body>
</html>
<script>
// object   前面说了对象就是多个值与方法的合集  可以很多地方调用 简单一点就是 键值对  key  value
var obj={
    lll:"ni"// 键 如果是数字 会自动转换为 字符串不用担心
}
var obj={
    pp:"555"
}
// 对象的每一个键名又称为“属性”（property），它的“键值”可以是任何数据类型。如果一个属性的值为函数，通常把这个属性称为“方法”，它可以像函数那样调用。

var obj = {
  p: function (x) { 
    return 2 * x;
  }
};

obj.p(1) // 2 p 是键 的名字 可以是函数

//  比如这样
 var obj1={};
 var obj2={bar:"你好世界"};
  obj1.foo=obj2;
  obj1.foo.bar// 你好 就是链式调用 其实即使赋值操作 第三个调用第一个 深入调用 借用的意思啊；
//   属性可以动态创建，不必在对象声明时就指定。
var obj = {};
obj.foo = 123;
obj.foo // 123
// 对象的引用
// 如果不同的变量名指向同一个对象，
// 那么它们都是这个对象的引用，也就是说指向同一个内存地址。修改其中一个变量，会影响到其他所有变量。
var o1 = {};
var o2 = o1;
o1.a=1;
o2.a//1 上面代码中，o1和o2指向同一个对象，因此为其中任何一个变量添加属性，
// 另一个变量都可以读写该属性。


// 属性是否存在：in 运算符
// in运算符用于检查对象是否包含某个属性（注意，检查的是键名，不是键值），如果包含就返回true，否则返回false。它的左边是一个字符串，表示属性名，右边是一个对象。

var obj = { p: 1 };
'p' in obj // true
'toString' in obj // true
// 你看到了 这里并没有 tostring 属性但是为 true  因为是继承的原因
//  你也可以使用 hasOwnProprty 方法做一下判断

 var obj={};
 if('tostring' in obj){
     console.log( obj.hasOwnProprty('toString'));//fale
 }
//  属性的遍历：for...in 循环
// for...in循环用来遍历一个对象的全部属性。


var obj = {a: 1, b: 2, c: 3};

for (var i in obj) {
  console.log('键名：', i);
  console.log('键值：', obj[i]);
}
// 键名： a
// 键值： 1
// 键名： b
// 键值： 2
// 键名： c
// 键值： 3

 for (const key in object) {
     if (Object.hasOwnProperty.call(object, key)) {
         const element = object[key];
         
     } 
 } //他不仅会遍历自身的属性 还会遍历 继承的属性  但是他会逃过 不可以遍历的属性 不可以枚举的属性


//  如果继承的属性是可遍历的，那么就会被for...in循环遍历到。但是，一般情况下，都是只想遍历对象自身的属性，所以使用for...in的时候，应该结合使用hasOwnProperty方法，在循环内部判断一下，某个属性是否为对象自身的属性。

var person = { name: '老张' };

for (var key in person) {
  if (person.hasOwnProperty(key)) {
    console.log(key);
  }
}
// na

</script>